package com.dao.impl;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.bean.FollowObj;
import com.bean.HeadTag;
import com.bean.HotCityObj;
import com.bean.Locality;
import com.bean.TagObj;
import com.bean.UserList;
import com.bean.UserLogin;
import com.bean.WeiboContext;
import com.bean.ZanMessage;
import com.dao.WeiboContextDao;
import com.util.CodeUtil;
import com.util.DateUtil;
import com.util.Domain;
import com.util.LoggerUtil;
import com.util.Pager;

@Component
public class WeiboContextDaoImpl implements WeiboContextDao{
	public static Logger logger=Logger.getLogger(WeiboContextDaoImpl.class);
	@Autowired
	private MongoTemplate mongoTemplate;



	@Override
	public Pager<WeiboContext> selectListByPageArea(Integer curPage,
			Integer pageSize, String areaId,String tag) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
	    Criteria criteria = Criteria.where("areaId").is(new ObjectId(areaId));
	    
	    if(tag!=null&&!tag.equals("")){
	    	String tag1=Domain.typesMap.get(tag);
	    	if(tag1!=null){
	    		criteria.and("users.types").is(tag1);
	    	}
	    	else if(tag1==null){
	    		criteria.and("tag").in(tag);
	    	}
	    }
		List<WeiboContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}

	@Override
	public Pager<WeiboContext> selectListByPageAreaZan(Integer curPage,
			Integer pageSize, String areaId) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
	    Criteria criteria = Criteria.where("areaId").is(new ObjectId(areaId));
		List<WeiboContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}


	@Override
	public Pager<WeiboContext> selectListByPageWeiboid(Integer curPage,
			Integer pageSize, String userId) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		List<WeiboContext> data=mongoTemplate.find(
				new Query(Criteria.where("users._id").is(new ObjectId(userId))).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(Criteria.where("users._id").is(new ObjectId(userId))), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	
	@Override
	public Pager<WeiboContext> selectListByPageWeiboidAndArea(
			Integer curPage, Integer pageSize, String userId,String areaId) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
	    Criteria criteria = Criteria.where("areaId").is(new ObjectId(areaId))
	    		.and("users._id").is(new ObjectId(userId));
		List<WeiboContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}

	@Override
	public Map<String, Object> selectPicByPageWeiboidAndTime(String userId) throws ParseException{
		Map<String,Object> map=new HashMap<String, Object>();
		List<String> times=DateUtil.allTime();
		List<Map<String, Object>> listMap=new ArrayList<>();
		for(String time:times){
			Pattern pattern = Pattern.compile(time,Pattern.CASE_INSENSITIVE);   
		    Criteria criteria = Criteria.where("publishDate").regex(pattern.toString())
		    		.and("users._id").is(new ObjectId(userId));
		    List<WeiboContext> data=mongoTemplate.find(
					new Query(criteria).skip(0).limit(15).with(new Sort(Sort.Direction.DESC,"rating")).
						with(new Sort(Sort.Direction.DESC,"publishDate")), 
						WeiboContext.class);
			List<String> imagesList=new ArrayList<String>();
			int i =0 ;
			for(WeiboContext weiboContent:data){
				if(i==9){
					break;
				}
				String images[]=weiboContent.getImgs();
				for(String image:images){
					imagesList.add(image);
					i++;
					if(i==9){
						break;
					}
				}
			}
			if(imagesList.size()>0){
				Map<String, Object> maps=new HashMap<String, Object>();
				maps.put("dateTime", time);
				maps.put("imgs", imagesList);
				listMap.add(maps);
			}
		}
		map.put("data", listMap);
		return map;
	}
	@Override
	public Pager<WeiboContext> selectFollow(Integer curPage,Integer pageSize,String id){
		UserLogin user=mongoTemplate.findById(id, UserLogin.class);
		List<ObjectId> strs=new ArrayList<ObjectId>();
		if(user!=null&user.getFollow()!=null){
			for(FollowObj obj:user.getFollow()){
				strs.add(new ObjectId(obj.getFollowId()));
			}
		}
		Criteria criteria=Criteria.where("users._id").in(strs);
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		List<WeiboContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	
	@Override
	public Pager<WeiboContext> selectOfficialList(Integer curPage,
			Integer pageSize,String userId){
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		List<WeiboContext> data=mongoTemplate.find(
				new Query(Criteria.where("users._id").is(new ObjectId(userId))).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		long count=mongoTemplate.count(new Query(Criteria.where("users._id").is(new ObjectId(userId))), WeiboContext.class);
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	
	
	@Override
	public Pager<WeiboContext> selectOfficialPageList(Integer curPage,
			Integer pageSize){
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		
		Criteria criteria=Criteria.where("users.types").is("org");
		List<WeiboContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), WeiboContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	@Override
	public Pager<WeiboContext> selectByTag(Integer curPage,
			Integer pageSize,String tag,Double jingPoint,Double weiPoint){
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		Query query=new Query();
		String tag1=Domain.typesMap.get(tag);
		if(tag1==null){
			query.addCriteria(Criteria.where("tag").in(tag));
		}else if(tag1.equalsIgnoreCase(Domain.tag_tuijian)){
			query.addCriteria(Criteria.where("rating").is(2));
		}else if(tag1.equalsIgnoreCase(Domain.tag_dangdi)){
			if(jingPoint!=null&&weiPoint!=null){
				//Point point=new Point(weiPoint,jingPoint );
				//Point location=new Point(jingPoint,weiPoint);
				//Country countries=mongoTemplate.findOne(new Query(Criteria.where("location.coordinates").in(str)), Country.class);
				/*GeoResults<Locality> locResults=mongoTemplate.geoNear(NearQuery.near(point, metric)(point).maxDistance(10), Locality.class);
				if(locResults!=null&&locResults.getContent().size()>0){
					System.err.println(locResults.getContent().toString());
				}
				for(GeoResult<Locality> locResult:locResults){
					System.out.println(locResult.getContent().getZhName());
				}*/
				//if(countries==null){
					///Locality localities=mongoTemplate.findOne(new Query(Criteria.where("location.coordinates").in(str)), Locality.class);
					//if(localities!=null){
					//	query.addCriteria(Criteria.where("area").in(localities.getZhName()));
					//}
				//}else{
				//	query.addCriteria(Criteria.where("area").is(countries.getZhName()));
				//}
			}
		}
		else{
			query=new Query(Criteria.where("users.types").is(tag1));
		}
		query.addCriteria(Criteria.where("content").nin(""));
		List<WeiboContext> weibo=mongoTemplate.find(
				query.skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					WeiboContext.class);
		List<WeiboContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(weibo.size());
		for(Integer index:indexes){
			data.add(weibo.get(index));
		}
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(mongoTemplate.count(query, WeiboContext.class))));
		
		return pager;
	}
	
	public Map<String, Object> findById(String id,String userId,JSONObject logs){
		Map<String, Object> map=new HashMap<String, Object>();
		try {
			WeiboContext weiboContext=mongoTemplate.findById(id, WeiboContext.class);
			if(weiboContext!=null){
				if(StringUtils.isNotEmpty(userId)){
					//UserLogin userLogin=mongoTemplate.findById(userId, UserLogin.class);
					long countFollow=mongoTemplate.count(new Query(Criteria.where("_id").is(userId).and("follow.followId").is(weiboContext.getUsers().getId())), UserLogin.class);
					if(countFollow>0){
						weiboContext.getUsers().setIsFollowed("true");
					}else{
						weiboContext.getUsers().setIsFollowed("false");
					}
					long count =mongoTemplate.count(new Query(Criteria.where("msg_id").
							is(id).and("user_id").is(userId).and("is_delete").is(Domain.zan_message_is_delete_n)), ZanMessage.class);
					if(count>0){
						weiboContext.setIsZan("true");
					}else{
						weiboContext.setIsZan("false");
					}
				}else{
					weiboContext.getUsers().setIsFollowed("false");
					weiboContext.setIsZan("false");
				}
				
				map.put("result", "success");
				map.put("rows",weiboContext);
				LoggerUtil.backlogsSuccess(logs, logger);
			}else{
				map.put("result", "false");
				LoggerUtil.backlogsFalseNOData(logs, logger);
			}
		} catch (Exception e) {
			e.printStackTrace();
			map.put("code", "101");
			LoggerUtil.backlogsFalseError(logs, logger,e);
			return map;
		}
		return map;
	}
	@Override
	public Map<String, Object> updateZanNum(String id,String user_id){
		Map<String, Object> map=new HashMap<String, Object>();
		try {
			Query zanQuery=new Query(Criteria.where("types")
					.is(Domain.zan_message_types_zan).and("user_id").is(user_id).and("msg_id").is(id).and("is_delete").is(Domain.zan_message_is_delete_n)
					.and("text_types").is(Domain.zan_message_text_types_weibo));
			List<ZanMessage> zanMessages=mongoTemplate.find(zanQuery, ZanMessage.class);
			if(zanMessages!=null&&zanMessages.size()>0){
				mongoTemplate.updateMulti(zanQuery, new Update().set("is_delete", Domain.zan_message_is_delete_y), ZanMessage.class);
				Query query=new Query(Criteria.where("id").is(id));
				Update update=new Update();
				update.inc("zanNum2", -1);
				mongoTemplate.findAndModify(query, update, WeiboContext.class);
				map.put("code", "107");
				return map;
			}
			Query query=new Query(Criteria.where("id").is(id));
			Update update=new Update();
			update.inc("zanNum2", 1);
			mongoTemplate.findAndModify(query, update, WeiboContext.class);
			//ZanMessage zanMessage=new ZanMessage(Domain.zan_message_text_types_weibo,user_id,id,Domain.zan_message_is_delete_n,new Date());
			//mongoTemplate.insert(zanMessage);
			map.put("code", "0");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			map.put("code", "101");
		}
		return map;
	}
	public Pager<WeiboContext> selectFirstWeibo(Integer curPage,
			Integer pageSize,String uId){
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		UserLogin user=mongoTemplate.findById(uId, UserLogin.class);
		List<String> tags=new ArrayList<>();
		List<ObjectId> hotCities=new ArrayList<>();
		List<ObjectId> follows=new ArrayList<ObjectId>();
		if(user!=null){
			ArrayList<TagObj> tagObjs=user.getTagObjs();
			ArrayList<HotCityObj> hotCityObjs=user.getHotCityObjs();
			ArrayList<FollowObj> followObjs=user.getFollow();
			int index1=(int) Math.round(Math.random()*(Domain.headTagSize-1));
			int index2=(int) Math.round(Math.random()*(Domain.headTagSize-1));
			if(index1==index2){
				HeadTag headTag1=mongoTemplate.findOne(new Query().skip(index1).limit(1), HeadTag.class);
				tags.add(headTag1.getTag());
			}else{
				HeadTag headTag2=mongoTemplate.findOne(new Query().skip(index2).limit(1), HeadTag.class);
				HeadTag headTag1=mongoTemplate.findOne(new Query().skip(index1).limit(1), HeadTag.class);
				tags.add(headTag1.getTag());
				tags.add(headTag2.getTag());
			}
			if(tagObjs!=null&&tagObjs.size()>0){
				for(TagObj obj:tagObjs){
					tags.add(obj.getTagObj());
				}
			}
			if(hotCityObjs!=null&&hotCityObjs.size()>0){
				for(HotCityObj obj:hotCityObjs){
					hotCities.add(obj.getCityId());
				}
			}
			int index3=(int) Math.round(Math.random()*(Domain.hotCitySize-1));
			int index4=(int) Math.round(Math.random()*(Domain.hotCitySize-1));
			if(index1==index2){
				Locality loca1=mongoTemplate.findOne(new Query().skip(index3).limit(1), Locality.class);
				hotCities.add(new ObjectId(loca1.getId()));
			}else{
				Locality loca1=mongoTemplate.findOne(new Query().skip(index3).limit(1), Locality.class);
				Locality loca2=mongoTemplate.findOne(new Query().skip(index4).limit(1), Locality.class);
				hotCities.add(new ObjectId(loca1.getId()));
				hotCities.add(new ObjectId(loca2.getId()));
			}
			int index5=(int) Math.round(Math.random()*(Domain.hotBigVSize-1));
			int index6=(int) Math.round(Math.random()*(Domain.hotBigVSize-1));
			if(index1==index2){
				UserList u1=mongoTemplate.findOne(new Query().skip(index5).limit(1).with(new Sort(Sort.Direction.DESC,"followed")), UserList.class);
				follows.add(new ObjectId(u1.getAid()));
			}else{
				UserList u1=mongoTemplate.findOne(new Query().skip(index5).limit(1).with(new Sort(Sort.Direction.DESC,"followed")), UserList.class);
				UserList u2=mongoTemplate.findOne(new Query().skip(index6).limit(1).with(new Sort(Sort.Direction.DESC,"followed")), UserList.class);
				follows.add(new ObjectId(u1.getAid()));
				follows.add(new ObjectId(u2.getAid()));
			}
			if(followObjs!=null&&followObjs.size()>0){
				for(FollowObj obj:followObjs){
					follows.add(new ObjectId(obj.getFollowId()));
				}
			}
		}
		Query query=new Query();
		Criteria[] cts=new Criteria[4];
		cts[0]=Criteria.where("tag").in(tags);
		cts[1]=Criteria.where("areaId").in(hotCities);
		cts[2]=Criteria.where("users._id").in(follows);
		cts[3]=Criteria.where("rating").is(2);
		query.addCriteria(new Criteria().orOperator(cts));
		List<WeiboContext> weibos=mongoTemplate.find(query.skip(pager.getStart()).
				limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"publishDate")), WeiboContext.class);
		List<WeiboContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(weibos.size());
		for(Integer index:indexes){
			data.add(weibos.get(index));
		}
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(mongoTemplate.count(query, WeiboContext.class))));
		return pager;
	}

	@Override
	public Pager<WeiboContext> selectUserAreaWeibo(Integer curPage,
			Integer pageSize, String uId, String areaId) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		Query query=new Query(Criteria.where("users._id").is(new ObjectId(uId)).and("areaId").is(new ObjectId(areaId)));
		
		List<WeiboContext> weibos=mongoTemplate.find(query.skip(pager.getStart()).limit(pager.getPageSize()), WeiboContext.class);
		List<WeiboContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(weibos.size());
		for(Integer index:indexes){
			data.add(weibos.get(index));
		}
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(mongoTemplate.count(query, WeiboContext.class))));
		return pager;
	}
	public Pager<WeiboContext> selectByFindRelate(Integer curPage,
			Integer pageSize, String weiboId) {
		Pager<WeiboContext> pager=new Pager<WeiboContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		WeiboContext weibo=mongoTemplate.findById(weiboId, WeiboContext.class);
		Query query =new Query();
		if(weibo!=null){
			String uId=weibo.getUsers().getId();
			String []tags=weibo.getTag();
			if(tags!=null&&tags.length>0){
				Criteria []cts=new Criteria[2];
				cts[0]=Criteria.where("tag").in(Arrays.asList(tags));
				cts[1]=Criteria.where("users._id").is(new ObjectId(uId));
				query.addCriteria(new Criteria().orOperator(cts));
			}else{
				query.addCriteria(Criteria.where("users._id").is(new ObjectId(uId)));
			}
		}
		
		List<WeiboContext> weibos=mongoTemplate.find(query.skip(pager.getStart()).limit(pager.getPageSize()), WeiboContext.class);
		List<WeiboContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(weibos.size());
		for(Integer index:indexes){
			data.add(weibos.get(index));
		}
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(mongoTemplate.count(query, WeiboContext.class))));
		return pager;
	}
	
}
